package com.blkj.iam.core.security.filter;

import com.blkj.iam.common.constant.SecurityConstants;
import com.blkj.iam.common.constant.StatusConstants;
import com.blkj.iam.common.result.ResultCode;
import com.blkj.iam.common.util.ResponseUtils;
import com.blkj.iam.system.model.entity.Tenant;
import com.blkj.iam.system.model.entity.User;
import com.blkj.iam.system.service.TenantService;
import com.blkj.iam.system.service.UserService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpMethod;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * @description: 租户校验器
 * @author: Ethan
 * @create: 2025-04-22
 **/
public class TenantAndUserValidationFilter extends OncePerRequestFilter {

    private static final AntPathRequestMatcher LOGIN_PATH_REQUEST_MATCHER = new AntPathRequestMatcher(SecurityConstants.LOGIN_PATH, HttpMethod.POST.name());

    public static final String LOGIN_TENANT_ID = "tenantId";
    public static final String LOGIN_USERNAME = "username";

    private final TenantService tenantService;
    private final UserService userService;


    public TenantAndUserValidationFilter(UserService userService, TenantService tenantService) {
        this.userService = userService;
        this.tenantService = tenantService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 检查是否是登录请求
        if (LOGIN_PATH_REQUEST_MATCHER.matches(request)) {
            try {
                // 从请求中获取租户ID和用户名
                long tenantId = Long.parseLong(request.getParameter(LOGIN_TENANT_ID));
                String username = request.getParameter(LOGIN_USERNAME);

                // 校验租户状态
                Tenant tenant = tenantService.getById(tenantId);
                if (StatusConstants.DISABLE.equals(tenant.getStatus())) {
                    ResponseUtils.writeErrMsg(response, ResultCode.TENANT_VERIFICATION_CODE_EXPIRED);
                    return;
                }

                // 校验用户是否存在
                User userByTenant = userService.getUserByTenant(username, tenantId);
                if (userByTenant == null) {
                    ResponseUtils.writeErrMsg(response, ResultCode.TENANT_USER_VERIFICATION_CODE_EXPIRED);
                    return;
                }
            } catch (Exception ex) {
                // 安全上下文清除保障（防止上下文残留）
                SecurityContextHolder.clearContext();
                ResponseUtils.writeErrMsg(response, ResultCode.ACCESS_TENANT_INVALID);
                return;
            }
        }

        // 如果是登录请求且校验通过，或者非登录请求，则继续后续的过滤器链
        filterChain.doFilter(request, response);
    }
}
